package logger

import (
	"bytes"
	"path/filepath"
	"runtime"
	"time"
)

// Formatter 零分配日志格式化器（经过安全化处理：返回字符串时复制，避免对象池复用引发的数据串扰）
type Formatter struct {
	bufferPool *BufferPool
}

// NewFormatter 创建新的格式化器
func NewFormatter() *Formatter {
	return &Formatter{
		bufferPool: NewBufferPool(),
	}
}

// FormatFileLineAt 构建写入文件的日志行（不包含颜色）
// 参数：固定时间、等级与原始消息；可选是否附带源码信息
func (f *Formatter) FormatFileLineAt(level Level, msg string, ts time.Time, enableSource bool) string {
	return f.formatFileLineToBuffer(level, msg, ts, enableSource)
}

// formatFileLineToBuffer 内部优化版本，减少内存分配
func (f *Formatter) formatFileLineToBuffer(level Level, msg string, ts time.Time, enableSource bool) string {
	buf := f.bufferPool.Get()
	defer f.bufferPool.Put(buf)

	// 时间戳
	f.formatTimestamp(buf, ts)
	// 等级
	WriteString(buf, " |")
	WriteString(buf, level.String())
	WriteString(buf, "| ")
	// 消息
	WriteString(buf, msg)
	// 源码信息
	if enableSource {
		sourceInfo := f.getSourceInfo()
		WriteString(buf, sourceInfo)
	}
	buf.WriteByte('\n')

	// 返回安全复制
	return buf.String()
}

// FormatConsoleLineAt 构建控制台输出的日志行（仅等级带颜色）
// 参数：固定时间、等级与原始消息；可选是否附带源码信息
func (f *Formatter) FormatConsoleLineAt(level Level, msg string, ts time.Time, enableSource bool) string {
	return f.formatConsoleLineToBuffer(level, msg, ts, enableSource)
}

// formatConsoleLineToBuffer 内部优化版本，减少内存分配
func (f *Formatter) formatConsoleLineToBuffer(level Level, msg string, ts time.Time, enableSource bool) string {
	buf := f.bufferPool.Get()
	defer f.bufferPool.Put(buf)

	// 时间戳
	f.formatTimestamp(buf, ts)
	// 等级（彩色）- 优化版本，避免Sprint的内存分配
	WriteString(buf, " |")
	// 直接写入颜色代码和等级文本
	f.writeColoredLevel(buf, level)
	WriteString(buf, "| ")
	// 消息
	WriteString(buf, msg)
	// 源码信息
	if enableSource {
		sourceInfo := f.getSourceInfo()
		WriteString(buf, sourceInfo)
	}
	buf.WriteByte('\n')

	// 返回安全复制
	return buf.String()
}

// formatTimestamp 零分配时间戳格式化（优化版本）
func (f *Formatter) formatTimestamp(buf *bytes.Buffer, t time.Time) {
	year, month, day := t.Date()
	hour, min, sec := t.Clock()
	nano := t.Nanosecond()

	// 使用更高效的格式化方式
	WriteIntWithPadding(buf, year, 4)
	buf.WriteByte('-')
	WriteIntWithPadding(buf, int(month), 2)
	buf.WriteByte('-')
	WriteIntWithPadding(buf, day, 2)
	buf.WriteByte(' ')
	WriteIntWithPadding(buf, hour, 2)
	buf.WriteByte(':')
	WriteIntWithPadding(buf, min, 2)
	buf.WriteByte(':')
	WriteIntWithPadding(buf, sec, 2)
	buf.WriteByte('.')
	WriteIntWithPadding(buf, nano/1000000, 3)
}

// FormatDirectToBuffer 直接格式化到现有buffer，避免字符串分配
// 返回格式化后的字符串长度，用于控制台和文件输出
func (f *Formatter) FormatDirectToBuffer(buf *bytes.Buffer, level Level, ts time.Time, enableSource bool, forConsole bool) {
	// 时间戳
	f.formatTimestamp(buf, ts)
	// 等级
	WriteString(buf, " |")
	if forConsole {
		// 控制台版本：彩色等级
		f.writeColoredLevel(buf, level)
	} else {
		// 文件版本：纯文本等级
		WriteString(buf, level.String())
	}
	WriteString(buf, "| ")
	// 源码信息 - 零分配版本
	if enableSource {
		f.writeSourceInfoDirect(buf)
	}
	buf.WriteByte('\n')
}

// writeColoredLevel 写入彩色等级文本，避免Sprint的内存分配
func (f *Formatter) writeColoredLevel(buf *bytes.Buffer, level Level) {
	// 获取颜色样式
	style := level.ColorStyle()
	// 手动构建ANSI颜色代码，避免Sprint分配
	buf.WriteString("\033[")
	// 前景色
	if len(style) > 0 {
		WriteInt(buf, int(style[0]))
	}
	// 背景色
	if len(style) > 1 {
		buf.WriteString(";")
		WriteInt(buf, int(style[1]))
	}
	buf.WriteString("m")
	// 等级文本
	WriteString(buf, level.String())
	// 重置颜色
	buf.WriteString("\033[0m")
}

// writeSourceInfoDirect 直接写入源码信息到buffer，零分配版本
func (f *Formatter) writeSourceInfoDirect(buf *bytes.Buffer) {
	_, file, line, ok := runtime.Caller(5) // 跳过5层调用栈（增加了一层）
	if !ok {
		return
	}

	// 直接写入到buffer，避免字符串分配
	fileName := filepath.Base(file)
	WriteString(buf, " [")
	WriteString(buf, fileName)
	buf.WriteByte(':')
	WriteInt(buf, line)
	buf.WriteByte(']')
}

// getSourceInfo 获取源码信息（安全字符串，不复用对象池内存）
// getSourceInfo 获取源码信息（优化版本，减少内存分配）
func (f *Formatter) getSourceInfo() string {
	_, file, line, ok := runtime.Caller(4) // 跳过4层调用栈
	if !ok {
		return ""
	}

	// 直接使用文件名，避免路径计算的内存分配
	fileName := filepath.Base(file)

	buf := f.bufferPool.Get()
	defer f.bufferPool.Put(buf)

	WriteString(buf, " [")
	WriteString(buf, fileName)
	buf.WriteByte(':')
	WriteInt(buf, line)
	buf.WriteByte(']')

	// 返回安全复制
	return buf.String()
}

// 全局格式化器实例
var globalFormatter = NewFormatter()

// FormatFileLineAt 全局包装
func FormatFileLineAt(level Level, msg string, ts time.Time, enableSource bool) string {
	return globalFormatter.FormatFileLineAt(level, msg, ts, enableSource)
}

// FormatConsoleLineAt 全局包装
func FormatConsoleLineAt(level Level, msg string, ts time.Time, enableSource bool) string {
	return globalFormatter.FormatConsoleLineAt(level, msg, ts, enableSource)
}
